#ifndef BLOCKREADER_H
#define BLOCKREADER_H

#include "volinterface.h"

#include <QtGui>
#include <QtCore>

#include "H5Cpp.h"
using namespace H5;

class BlockReader : public QObject, VolInterface
{
  Q_OBJECT
  Q_INTERFACES(VolInterface)

 public :
  ~BlockReader();

  void init();
  void setFilename(QList<QString>);

  void setMemorySize(int);
  void setTextureSize(int);
  void setGridSize(int, int, int);
  void setUserLimits(Vec, Vec);
  void gridSize(int&, int&, int&);
  void gridSize(int, int&, int&, int&);
  void p2gridSize(int&, int&, int&);
  void compactGridSize(int&, int&, int&);
  void blockedGridSize(int&, int&, int&);
  void p2blockedGridSize(int&, int&, int&);

  int* get1dHistogram();
  int* get2dHistogram();
  int* get1dHistogram(int);
  int* get2dHistogram(int);

  uchar *blockLevel();
  uchar* blockedData();
  uchar* auxData();
  int blockSize();

  bool initIdentifyValidBlocks(int);
  bool initIdentifyValidBlocks(uchar*);
  int minLod();
  int minLod(int);
  int minLod(uchar*);
  
  void setLodLevel(int);

  void loadBlocks(QList<Vec>, int);
  void loadAllValidBlocks(int);
  uchar* wholeVolume(int);
  uchar* loadSingleBlock(int, int, int, int);

  void setIsovalue(int);

 private :
  int m_nVolumes;
  QList<QString> m_fileName;

  H5File* m_hdf5file[4];
  Group* m_group[4][10];
  DataSet m_hdf5Dataset[4][10];
  DataSet m_minmaxDataset[4][10];
  IntType m_dataType;

  int m_minLevel;
  int m_blockSize;
  int m_overlap;
  int m_odepth, m_orows, m_ocols;
  int m_depth, m_rows, m_cols;
  int m_p2depth, m_p2rows, m_p2cols;
  int m_compactdepth, m_compactrows, m_compactcols;

  qint64 m_nblocks, m_nblocks0;
  int m_dblocks, m_rblocks, m_cblocks;
  int m_p2dblocks, m_p2rblocks, m_p2cblocks;
  
  uchar *m_blockLevel;
  uchar *m_savedblockLevel;

  bool m_allBlocks;
  qint64 m_maxCacheSize;
  QList<qint64> m_lru;
  QMap <qint64, uchar*> m_blockCache;

  uchar* m_tmpV;
  uchar* m_data;
  uchar* m_auxdata;
  uchar *m_limits[4][10];

  int m_cblkno[10];
  int m_lblkno[10];
  int m_maxlodLevel;
  int m_memorySize;
  qint64 m_spareMem;
  
  qint64 m_maxtexSize;

  int m_slevel;
  int m_isoval;
  int m_currLod;

  ushort *m_summedAreaTable;

  Vec m_boxMinUser, m_boxMaxUser;

  int *m_1dHistogram[4], *m_2dHistogram[4];

  void loadBlock(int,
		 int, int, int, int,
		 int, int,
		 uchar*);
  void readBlock(int, int, hsize_t*, uchar*);
  void copyBlock(int, int, int, int);

  void generateHistograms(int, int);
  void generateHistograms(float*, float*, int*, int*);
};

#endif
